/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.ipfw.cs590.cheat.util;

import edu.ipfw.cs590.cheat.UserRights;
import java.util.ResourceBundle;
import javax.servlet.http.HttpSession;

/**
 *
 * @author safar
 */
public class Authentication {
    /**
     * Resource bundle.
     */
    private static ResourceBundle props = ResourceBundle.getBundle("edu/ipfw/cs590/cheat/CheatClient");
    /**
     * Admin access level.
     */
    private static int ADMIN_LEVEL;
    /**
     * Faculty access level.
     */
    private static int FACULTY_LEVEL;
    /**
     * Student access level.
     */
    private static int STUDENT_LEVEL;
    /**
     * Rights name.
     */
    public static String SESSION_NAME_RIGHTS;
    /**
     * email name.
     */
    public static String SESSION_NAME_EMAIL;
    /**
     * Token name.
     */
    public static String SESSION_NAME_TOKEN;
    /**
     * First Name name.
     */
    public static String SESSION_NAME_FIRST_NAME;
    /**
     * Last Name name.
     */
    public static String SESSION_NAME_LAST_NAME;
    
    /**
     * Static initialization of properties
     */
    static {
        System.out.println("Bringing up client authentication system...");
        try {
            //Initialize from properties.
            SESSION_NAME_RIGHTS = props.getString("cheat.session.access.type");
            SESSION_NAME_EMAIL = props.getString("cheat.session.email");
            SESSION_NAME_TOKEN = props.getString("cheat.session.token");
            SESSION_NAME_FIRST_NAME = props.getString("cheat.session.name.first");
            SESSION_NAME_LAST_NAME = props.getString("cheat.session.name.last");
            STUDENT_LEVEL = Integer.parseInt(props.getString("cheat.session.access.type.student.level"));
            FACULTY_LEVEL = Integer.parseInt(props.getString("cheat.session.access.type.teacher.level"));
            ADMIN_LEVEL = Integer.parseInt(props.getString("cheat.session.accces.type.admin.level"));
        } catch (Exception exc) {
            exc.printStackTrace();
        } finally {
            System.out.println("Rights Session Email: " + SESSION_NAME_EMAIL);
            System.out.println("Rights Session Name:  " + SESSION_NAME_RIGHTS);
            System.out.println("Rights Session Token: " + SESSION_NAME_TOKEN);
            System.out.println("Rights Session First Name: " + SESSION_NAME_FIRST_NAME);
            System.out.println("Rights Session Last Name:  " + SESSION_NAME_LAST_NAME);
            System.out.println("Student Level: " + STUDENT_LEVEL);
            System.out.println("Faculty Level: " + FACULTY_LEVEL);
            System.out.println("Admin Level:   " + ADMIN_LEVEL);
        }
        System.out.println("Client authentication system loaded...");
    }

    /**
     * Is this an admin.
     * @param accessLevel the access level.
     * @return true if admin false otherwise.
     */
    public static boolean isAdmin(int accessLevel) {
        return (ADMIN_LEVEL & accessLevel) != 0;
    }

    /**
     * Is this an admin.
     * @param session Session.
     * @return true if admin false otherwise.
     */
    public static boolean isAdmin(HttpSession session) {
        try {
            return Authentication.isAdmin(
                    ((Integer) session.getAttribute(SESSION_NAME_RIGHTS)).intValue());
        } catch (Exception exc) {
            System.out.println("ERRRORR");
            return false;
        }
    }

    /**
     * Is this a student.
     * @param accessLevel access level.
     * @return true if student false otherwise.
     */
    public static boolean isStudent(int accessLevel) {
        return (STUDENT_LEVEL & accessLevel) != 0;
    }

    /**
     * Is this a student.
     * @param session session.
     * @return true if student false otherwise.
     */
    public static boolean isStudent(HttpSession session) {
        try {
            return Authentication.isStudent(
                    ((Integer) session.getAttribute(SESSION_NAME_RIGHTS)).intValue());
        } catch (Exception exc) {
            return false;
        }
    }

    /**
     * Is this a teacher.
     * @param accessLevel access level.
     * @return true if teacher false othwerise.
     */
    public static boolean isTeacher(int accessLevel) {
        return (FACULTY_LEVEL & accessLevel) != 0;
    }

    /**
     * Is this a teacher.
     * @param session session.
     * @return true if teacher false otherwise.
     */
    public static boolean isTeacher(HttpSession session) {
        try {
            return Authentication.isTeacher(
                    ((Integer) session.getAttribute(SESSION_NAME_RIGHTS)).intValue());
        } catch (Exception exc) {
            return false;
        }
    }

    /**
     * Calculate the access level for an account
     * @param rights rights.
     * @return int calculated access level.
     * @throws edu.ipfw.cs590.cheat.util.AccessLevelException
     */
    public static int calculateAccessLevel(UserRights rights) throws AccessLevelException {

        int accessLevel = 0;

        //Check for admin rights
        if (rights.equals(UserRights.ADMINISTRATOR)) {
            accessLevel += ADMIN_LEVEL;
        }

        //Check for instructor
        if (rights.equals(UserRights.INSTRUCTOR)) {
            accessLevel += FACULTY_LEVEL;
        }

        //Check for student
        if (rights.equals(UserRights.STUDENT)) {
            accessLevel += STUDENT_LEVEL;
        }

        if (accessLevel == 0) {
            throw new AccessLevelException("Invalid Access Type.");
        }

        return accessLevel;
    }
}

/**
 * Access level exception
 * @author SafarTimuro
 */
class AccessLevelException extends Exception {

    String message;

    /**
     * Constructor
     * @param msg
     */
    public AccessLevelException(String msg) {
        message = msg;
    }

    /**
     * Overriden to string.
     * @return
     */
    @Override
    public String toString() {
        return message;
    }
}
